package jdklearning.concurrent.thread;


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;

/**
 * JVM线程中断的条件只有两个，一个是抛异常，另外一个就是return。
 * 这里Quasar就是通过抛异常的方式来达到的，所以你会看到我上面的代码会抛出SuspendExecution
 *
 * 线程最佳实践: 每一个线程都设置名字,线程池设置group名字
 */
public class TheadLearning {

	public static final int THREAD_COUNT = 1000;

	public static final int LOOP_COUNT = 100;


	public void run() {
		DeadLockThread mt = new DeadLockThread();
		new Thread(mt, "张三").start();
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		new Thread(mt, "李四").start();
	}

	static class DeadLockThread implements Runnable {
		private final Object o1 = new Object();
		private final Object o2 = new Object();
		private boolean flag = true;
		

		@Override
		public void run() {
			if (flag) {
				flag = false;
				synchronized (o1) {
					System.out.println(Thread.currentThread().getName() + " have o1");
//					try {
//						Thread.sleep(100);
//					} catch (InterruptedException e) {
//						e.printStackTrace();
//					}
					synchronized (o2) {
						System.out.println(Thread.currentThread().getName() + " have o2");
					}
				}
			} else {
				flag = true;
				synchronized (o2) {
					System.out.println(Thread.currentThread().getName() + " have o2");
//					try {
//						Thread.sleep(100);
//					} catch (InterruptedException e) {
//						e.printStackTrace();
//					}
					synchronized (o1) {
						System.out.println(Thread.currentThread().getName() + " have o1");
					}
				}
			}
		}
	}
	
	public void threadSafe1() {
		CyclicBarrier startBarrier = new CyclicBarrier(THREAD_COUNT);
		CountDownLatch finishCdl = new CountDownLatch(THREAD_COUNT);
		MyThread1 mt = new MyThread1(startBarrier, finishCdl);
		for( int i = 0; i < THREAD_COUNT; i++){
			Thread thread = new Thread(mt, String.valueOf(i));
//			Thread t1 = new Thread(new MyThread1(), String.valueOf(i));
			thread.start();
//			try {
//				t1.join();
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}
		}

		try {
			finishCdl.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
//		System.out.println( outI );
//		System.out.println( outList.size() );
		System.out.println( mt.MyThread1I );
	}


	public static int outI = 0;
	public static List<Object> outList = new ArrayList<>();
	static class MyThread1 implements Runnable {

		public int MyThread1I = 0;
		private CyclicBarrier startBarrier;
		private CountDownLatch finishCdl;

		public MyThread1(CyclicBarrier startBarrier, CountDownLatch finishCdl) {
			this.startBarrier = startBarrier;
			this.finishCdl = finishCdl;
		}

		@Override
		public void run() {
			try {
				startBarrier.await();
				for(int i=0; i < LOOP_COUNT; i++){
					this.MyThread1I++;
					outI++;
				}
				finishCdl.countDown();
			} catch (InterruptedException | BrokenBarrierException e) {
				e.printStackTrace();
			}
		}
	}



	public static void threadSafe2() {
		// 用来测试的List
		List<Object> list = new ArrayList<>();
		// 线程数量(1000)
		// 用来让主线程等待threadCount个子线程执行完毕
		CountDownLatch countDownLatch = new CountDownLatch(THREAD_COUNT);
		// 启动threadCount个子线程
		for(int i = 0; i < THREAD_COUNT; i++) {
			Thread thread = new Thread(new MyThread2(list, countDownLatch));
			thread.start();
//			try {
//				thread.join();
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}
		}
//		try {
//			// 主线程等待所有子线程执行完成，再向下执行
//			countDownLatch.await();
//		}
//		catch (InterruptedException e){
//			e.printStackTrace();
//		}

		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		// List的size
		System.out.println(list.size());
	}

	static class MyThread2 implements Runnable {
		private List<Object> list;

		private CountDownLatch countDownLatch;

		public MyThread2(List<Object> list, CountDownLatch countDownLatch) {
			this.list = list;
			this.countDownLatch = countDownLatch;
		}

		@Override
		public void run() {
			// 每个线程向List中添加100个元素
			for(int i = 0; i < TheadLearning.LOOP_COUNT ; i++) {
				list.add(new Object());
			}
			// 完成一个子线程
			countDownLatch.countDown();
		}
	}


	public static void main(String[] args) {
		TheadLearning theadLearning = new TheadLearning();
		while (true){
			theadLearning.threadSafe1();
//			threadSafe2();
		}
	}
}



	